package org.df.ulab.bot.plugins.msn;

import net.sf.jml.MsnContact;
import net.sf.jml.MsnMessenger;
import net.sf.jml.MsnSwitchboard;
import net.sf.jml.event.MsnMessageListener;
import net.sf.jml.impl.MsnMessengerFactory;
import net.sf.jml.message.MsnControlMessage;
import net.sf.jml.message.MsnDatacastMessage;
import net.sf.jml.message.MsnInstantMessage;
import net.sf.jml.message.MsnSystemMessage;
import net.sf.jml.message.MsnUnknownMessage;
import net.sf.jml.message.p2p.MsnP2PMessage;

import org.df.ulab.bot.api.message.ImMessage;
import org.df.ulab.bot.api.message.Message;
import org.df.ulab.bot.util.communication.BaseCommunicationService;
import org.df.ulab.bot.util.core.StorageSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Daniel Filgueiras
 * 04/05/2011
 */
public class MsnService extends BaseCommunicationService implements MsnMessageListener {

	private static final Logger logger = LoggerFactory.getLogger(MsnService.class);
	
	private int	watchDog = 5;
	
	private String login;
	private String password;
	
	private MsnMessenger connection;
	
	@Override
	public boolean subscribe(String remoteId) {
		return false;
	}
	
	@Override
	public boolean unsubscribe(String remoteId) {
		return false;
	}
	
	@Override
	public void reply(Message message, CharSequence alert) {
		if (message instanceof ImMessage) {
			String to = ((ImMessage)message).getRemoteId();
			sendTextMessage(to,alert);
		} else {
			logger.warn("Can not reply message type: {}", message.getClass());
		}
	}

	@Override
	public void reply(Message message, DefaultMsgs msg) {
		reply(message, msg.toString());
	}

	@Override
	public void run() {
		logger.info("MSN Service thread running");
		MsnSettings msnSettings = StorageSystem.getInstance().load(MsnSettings.class, "msn", true);
		
		login = msnSettings.getLogin();
		password = msnSettings.getPassword();
		
		if(login == null || password == null) {
			logger.error("Login and Password not set");
			return;
		}
		
		try {
			connection = MsnMessengerFactory.createMsnMessenger(login, password);
			connection.setLogIncoming(false);
			connection.setLogOutgoing(false);
			connection.login();
			connection.addMessageListener(this);
			logger.info("MSN Service started");
			
			while(keepAlive) {
				sendPendingMessages();
				
				Thread.sleep(watchDog * 1000);
			}
			logger.info("Service keep-alive set to false");
		} catch(InterruptedException e) {
			logger.warn("Connection interrupted");
		} catch (Exception e) {
			logger.warn("Ops!!! Something bad happen.",e);
		} finally {
			logger.debug("Closing connection...");
			if (connection != null)
				connection.logout();
		}
	}
	
	private void sendPendingMessages() {
		Message toSend = getNextMessage();
		while (toSend != null) {
			if (toSend instanceof ImMessage) {
				ImMessage iMessage = (ImMessage)toSend;
				sendTextMessage(iMessage.getRemoteId(), toSend.toText());
			} else {
				logger.warn("Unknow message type {}", toSend.getClass());
			}
			
			toSend = getNextMessage();
		}
	}

	private void sendTextMessage(String remoteId, CharSequence text) {
		
		for (MsnSwitchboard switchboard : connection.getActiveSwitchboards()) {
			for (MsnContact contact : switchboard.getAllContacts()) {
				if (contact.getEmail().getEmailAddress().equals(remoteId)) {
					MsnInstantMessage reply = new MsnInstantMessage();
					reply.setContent(text.toString());
					switchboard.sendMessage(reply);
					return;
				}
			}
		}
		
		logger.warn("Could not find Switchboard for remote id: {}", remoteId);
	}

	@Override
	public void instantMessageReceived(MsnSwitchboard switchboard,
			MsnInstantMessage message, MsnContact contact) {
		
		addIncome(new MsnTextMessage(contact.getEmail().getEmailAddress(), message.getContent()));
	}
	
	
	@Override
	public void controlMessageReceived(MsnSwitchboard arg0,
			MsnControlMessage arg1, MsnContact arg2) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void offlineMessageReceived(String arg0, String arg1, String arg2,
			MsnContact arg3) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void p2pMessageReceived(MsnSwitchboard arg0, MsnP2PMessage arg1,
			MsnContact arg2) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void systemMessageReceived(MsnMessenger arg0, MsnSystemMessage arg1) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void unknownMessageReceived(MsnSwitchboard arg0,
			MsnUnknownMessage arg1, MsnContact arg2) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void datacastMessageReceived(MsnSwitchboard arg0,
			MsnDatacastMessage arg1, MsnContact arg2) {
		// TODO Auto-generated method stub
		
	}

}
